package com.wanban.downloader.utils

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSession
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager


object OkHttpClientProvider {

    private val client by lazy {
        // 日志
        val client = OkHttpClient.Builder()
            .connectTimeout(30L, TimeUnit.SECONDS)
            .readTimeout(30L, TimeUnit.SECONDS)
            .writeTimeout(30L, TimeUnit.SECONDS)
            .hostnameVerifier(hostnameVerifier)//配置
            .sslSocketFactory(sSLSocketFactory, x509TrustManager)//配置
        client.addInterceptor { chain ->
                // 以拦截到的请求为基础建立一个新的请求对象，而后插入Header
                val requestBuilder = chain.request().newBuilder()
                    .addHeader("Accept", "*/*")
                // 开始请求
                return@addInterceptor chain.proceed(requestBuilder.build())
            }
            .addInterceptor(RetryOkHttpInterceptor(3))
        return@lazy client.build()
    }

    fun getOkHttpClient(): OkHttpClient {
        return client
    }

    // 重试
    private class RetryOkHttpInterceptor(private val maxRetryTimes: Int): Interceptor {
        private var retryTimes: Int = 0
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            var response = chain.proceed(request)
            while (!response.isSuccessful && retryTimes < maxRetryTimes) {
                retryTimes++
                response = chain.proceed(request)
                // 重试之前等待一段时间
                TimeUnit.MILLISECONDS.sleep(2000)
            }
            return response
        }
    }


    private val hostnameVerifier: HostnameVerifier
        //获取HostnameVerifier
        get() = HostnameVerifier { s: String?, sslSession: SSLSession? -> true }

    private val x509TrustManager: X509TrustManager
        get() = object : X509TrustManager {
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }

    private val sSLSocketFactory: SSLSocketFactory
        //获取这个SSLSocketFactory
        get() {
            try {
                val sslContext = SSLContext.getInstance("SSL")
                sslContext.init(null, trustManager, SecureRandom())
                return sslContext.socketFactory
            } catch (e: Exception) {
                throw RuntimeException(e)
            }
        }
    private val trustManager: Array<TrustManager>
        //获取TrustManager
        get() = arrayOf(object : X509TrustManager {
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        })
}